package socket;

import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import demo.JfinalConfig;
import util.PushConsumer;

import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;

/**
 * Created by Administrator on 2016/11/23 0023.
 * <p>
 * 推送模块参数{date}，{student}
 */
public class ClockService {

    public static final int ST_REACH = 1;
    public static final int ST_LEAVE = 2;

    public static String handResult(String str) {
        String rs = "";
        if (str.length() < 10) {
            return rs;
        }
        // 第1-9为设备号，第10-21为时间（161115204911） 第22-31位为10位卡号
        String op = str.substring(21, 31);
        switch (op) {
            case "0000000000"://心跳包 #ACK 2015-05-09 08:14:08
                String d = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date());
                rs = "#ACK " + d;
                break;
            default:
                parseData(str);
        }
        return rs;
    }

    public static void parseData(String str) {
        /**
         * example
         * #000000011611171553250000000000000000AB5
         * 结构：（ 2-9位设备终端ID） + （10-21位十进制日期字符格式） + （22-31位卡号）+（32位打卡进校离校字段）
         * 1进校，2离校
         */
        String deviceId = str.substring(1, 9);
        String card = str.substring(21, 31);
        String date = str.substring(9, 21);
        int type = Integer.parseInt(str.substring(31, 32));

        JfinalConfig.start();
        saveToClockRecord(deviceId, card, date, type);

        //1.查询打卡学生信息
        String sql = "select s.name, s.id, s.classes_id, s.school_id from student s where s.card = ? limit 1";
        Record student = Db.findFirst(sql, card);

        if (student == null) {
            System.err.println("###cannot find the card: " + card);
            return;
        }

        Long id = saveToClock(date, type, student);

        sendPush(date, type, student, id);
    }

    private static void sendPush(String dateStr, int type, Record student, Long clockId) {
        if (student != null && (type == 1 || type == 2) && clockId != null) {//只推送进校和离校数据
            Record setting = getClockSetting(student.getBigDecimal("school_id"));
            String desc = setting.getStr("template_reach");
            if (type == ST_LEAVE) {
                desc = setting.getStr("template_leave");
            }

            if (StrKit.isBlank(desc)) {
                return;
            }

            String formatDate = "";
            try {
                java.util.Date date = new SimpleDateFormat("yyMMddHHmmss").parse(dateStr);
                formatDate = new SimpleDateFormat("HH时mm分").format(date);
            } catch (ParseException e) {
                e.printStackTrace();
            }

            desc = desc.replace("{date}", formatDate).replace("{student}", student.getStr("name"));

            Long sid = student.getBigDecimal("id").longValue();
            List<BigDecimal> list = Db.query("select parents_id from student_parents where student_id = ?", sid);
            for (BigDecimal pid : list) {//pid = BigDecimal.valueOf(407676);
                PushConsumer.send("child_" + pid, desc, clockId);
            }
        }

    }

    /**
     * 保存到clock_record表
     */
    public static int saveToClockRecord(String deviceId, String card, String dateStr, int type) {
        String sql = "INSERT INTO clock_record (id, device_id, card_id, type, start_time)" +
                " VALUES (nextval('clock_sequence'), ?, ?, ?, to_timestamp(?, 'yyMMddhh24miss'));";
        int i = 0;
        try {
//            Date date = new SimpleDateFormat("yyyyMMddHHmmss").parse(dateStr);
            i = Db.update(sql, deviceId, card, type, dateStr);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return i;
    }

    /**
     * 保存到clock表
     * 进校数据记录最早一次，离校数据记录最后一次打卡数据
     */
    public static Long saveToClock(String dateStr, int type, Record student) {
        Long id = null;
//            2.查询学校设置的打卡时间
        Record setting = getClockSetting(student.getBigDecimal("school_id"));

        String timeStr = dateStr.substring(8, 12);
        int reachLate = -1;//缺卡
        int leaveEarly = -1;
        Timestamp timestamp = null;
        try {
            timestamp = new Timestamp(new SimpleDateFormat("yyMMddHHmmss").parse(dateStr).getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        java.sql.Date date = new java.sql.Date(timestamp.getTime());

        if (type == ST_REACH) {//reach
            if (timeStr.compareTo(setting.getStr("reach_begin").replace(":", "")) >= 0 &&
                    timeStr.compareTo(setting.getStr("reach_end").replace(":", "")) <= 0) {//有效打卡时间
                reachLate = 0;
            } else {
                reachLate = 1;
            }
        } else if (type == ST_LEAVE) {//leave
            //先判断是特殊上学日还是普通上学日，再比较
            String leaveBegin = setting.getStr("leave_begin").replace(":", "");
            String leaveEnd = setting.getStr("leave_end").replace(":", "");
            int normalDays = Integer.parseInt(setting.getStr("normal_days").substring(2, 3));
            String specialDay = setting.getStr("special_days");

            int currDay = getDayOfWeek(date);

            if (specialDay != null && currDay == Integer.parseInt(specialDay)) {//特殊上学日
                leaveBegin = setting.getStr("special_leave_begin").replace(":", "");
                leaveEnd = setting.getStr("special_leave_end").replace(":", "");
            } else if (currDay >= normalDays) {//是否为正常日范围
                return null;
            }

            if (timeStr.compareTo(leaveBegin) >= 0 && timeStr.compareTo(leaveEnd) <= 0) {//有效打卡时间
                leaveEarly = 0;
            } else {
                leaveEarly = 1;
            }
        } else {//既不是进校也不是离校，则不保存
            return null;
        }
//            3.判断是否已有记录,并作处理
        Record r = Db.findFirst("select * from clock where date = ? " +
                "and student_id =? and classes_id = ?", date, student.get("id"), student.get("classes_id"));
        if (r == null || r.get("id") == null) {//未找到，则新增记录
            id = Db.queryLong("select nextval('clock_sequence')");
            Record obj = new Record();
            obj.set("student_id", student.get("id"))
                    .set("school_id", student.get("school_id"))
                    .set("classes_id", student.get("classes_id"))
                    .set("date", date)
                    .set("id", id)
                    .set("reach_late", reachLate)
                    .set("leave_early", leaveEarly);

            if (type == ST_REACH) {
                obj.set("reach_time", timestamp);
            } else {
                obj.set("leave_time", timestamp);
            }

            Db.save("clock", obj);
        } else {//找到记录，应为进校后离校的数据
            if (type == ST_LEAVE) {
                r.set("leave_time", timestamp).set("leave_early", leaveEarly);
                Db.update("clock", r);
            }
            id = r.getBigDecimal("id").longValue();//进校离校都作推送
        }
        return id;
    }

    private static Record getClockSetting(BigDecimal schoolId) {
        String sql = "select * from clock_setting where school_id = ? or school_id is null order by school_id nulls last limit 1";
        return Db.findFirst(sql, schoolId);
    }

    private static int getDayOfWeek(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int day = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return day == 0 ? 7 : day;//星期天
    }


    public static void main(String[] args) {
        JfinalConfig.start();
//        saveToClock("1001", "20161117082922", 1);
//        saveToClock("1001", "20161117180022", 2);
        //handResult("#00000001161130162123163500846800004D090");1636003686
//        handResult("#0000000116121008422116360036862000000A6");
//        PushConsumer.send("child_407676", "测试消息发送", 2390L);
        handResult("#0000000116121315211816360033442000008A4");
    }
}
